/*
 * brokerComunicator.cpp
 *
 *  Created on: 21/07/2014
 *      Author: nicolas
 */

#include "../defines.h"
#include "../ipc/Socket.h"
#include "../ipc/ColaMensajes.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>

bool negociarDireccion(Socket& sock, int& id) {
	MENSAJE_BROKER msg;

	sock.recv(&msg, sizeof(MENSAJE_BROKER));

	id = msg.id;

	return msg.esReceptor;
}

void sig_handler(int signo) {
	char mostrar[80];
	sprintf(mostrar, "Salida por borrado de cola\n");
	write(fileno(stdout), mostrar, strlen(mostrar));
}

int main(int argc, char **argv) {

	if (!(argc == 2 || argc == 4)) {
		perror("Cantidad de args incorrecta");
		exit(1);
	}

	char encabezado[80];
	sprintf(encabezado, "BrokerComunicator");
	openlog(encabezado, LOG_PID | LOG_CONS, LOG_LOCAL0);

	int sockFd = atoi(argv[1]);

	Socket sock(sockFd);
	MENSAJE_BROKER msg;
	MENSAJE_TOKEN tok;
	ColaMensajes cola(RUTA, COLABROKER);
	ColaMensajes colaRespuesta(RUTA, COLARESPUESTA);
	ColaMensajes colaToken(RUTA, COLATOKEN);

	int id;
	bool esReceptor;
	if (argc == 2) {
		esReceptor = negociarDireccion(sock, id);
	} else {
		id = atoi(argv[2]);
		esReceptor = atoi(argv[3]);
	}

	syslog(LOG_INFO, "Negocio direccion de datos, es receptor? %i", esReceptor);

	bool salir = false;

	if (esReceptor) {
		struct sigaction sa;
		memset(&sa, 0, sizeof(sa));
		sa.sa_handler = &sig_handler;
		sigaction(SIGUSR1, &sa, NULL);

		msg.destinatario = id;
		msg.tipo = TIPO_INFO_PID;
		msg.pid = getpid();
		colaRespuesta.enviar(&msg, TAM_MENSAJE_BROKER);
		while (!salir) {
			int leido = sock.recv(&msg, sizeof(MENSAJE_BROKER));
			if ((unsigned) leido < sizeof(MENSAJE_BROKER)) {
				syslog(LOG_INFO, "Error al recibir mensaje, se recibio: %i",
						leido);
				salir = true;
			} else if (msg.tipo == TIPO_FINALIZAR) {
				salir = true;
				msg.destinatario = id;
				colaRespuesta.enviar(&msg, TAM_MENSAJE_BROKER);
			} else if (msg.tipo == TIPO_TOKEN) {
				sock.recv(&tok, sizeof(MENSAJE_TOKEN));
				colaToken.enviar(&tok, TAM_MENSAJE_TOKEN);
				cola.enviar(&msg, TAM_MENSAJE_BROKER);
//				syslog(LOG_INFO, "Puso en cola mensaje de tipo %i", msg.tipo);
			} else {
				cola.enviar(&msg, TAM_MENSAJE_BROKER);
//				syslog(LOG_INFO, "Puso en cola mensaje de tipo %i", msg.tipo);
			}
		}
	} else {
		int pidPareja;

		while (!salir) {
			if (!colaRespuesta.recibir(&msg, TAM_MENSAJE_BROKER, id, false)) {
				kill(pidPareja, SIGUSR1);
				exit(1);
			}
			if (msg.tipo == TIPO_FINALIZAR) {
				salir = true;
				sock.send(&msg, sizeof(MENSAJE_BROKER));
			} else if (msg.tipo == TIPO_INFO_PID) {
				pidPareja = msg.pid;
			} else {
				int escrito = sock.send(&msg, sizeof(MENSAJE_BROKER));
//				syslog(LOG_INFO, "Saco de la cola mensaje de tipo %i",
//						msg.tipo);
				if ((unsigned) escrito < sizeof(MENSAJE_BROKER)) {
					syslog(LOG_INFO, "Error al recibir mensaje, se recibio: %i",
							escrito);
				}
			}
		}
	}

	sock.closeSock();

	return 0;

}

